﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

using WfhTrader.Core.Trading;

namespace WfhTrader.Core.Quote
{
    /// <summary>
    /// K线序列
    /// </summary>
    public class BarSeries
    {
        /// <summary>
        /// 包含的K线
        /// </summary>
        private List<Bar> bars;

        /// <summary>
        /// 证券
        /// </summary>
        public Security Security { get; private set; }

        /// <summary>
        /// K线单位
        /// </summary>
        public BarUnit BarUnit { get; private set; }


        /// <summary>
        /// K线更新事件
        /// </summary>
        public event PriceUpdateDelegate PriceUpdate;
        public delegate void PriceUpdateDelegate(BarSeries series);

        /// <summary>
        /// K线新开事件
        /// </summary>
        public event BarOpenDelegate BarOpen;
        public delegate void BarOpenDelegate(BarSeries series);

        /// <summary>
        /// K线完成事件
        /// </summary>
        public event BarCloseDelegate BarClose;
        public delegate void BarCloseDelegate(BarSeries series);


        /// <summary>
        /// 构造函数
        /// </summary>
        /// <param name="security">证券品种</param>
        /// <param name="barUnit">K线单位</param>
        /// <param name="size">K线数量</param>
        public BarSeries(Security security, BarUnit barUnit, int size = 240)
        {
            this.Security = security;
            this.BarUnit  = barUnit;

            this.bars = new List<Bar>(size);
        }

        /// <summary>
        /// 获取指定索引的K线（最新的一根的索引为零,如果不存在则为空）
        /// </summary>
        public Bar this[int index]
        {
            get
            {
                Bar bar   = null;
                int count = bars.Count - 1;

                if (0 <= index && index <= count)
                    bar = bars[count - index];

                return bar;
            }
        }

        /// <summary>
        /// 将一根新K线加入序列
        /// </summary>
        /// <param name="kLine">K线</param>
        public void Add(Bar bar)
        {
            this.bars.Add(bar);
        }

        /// <summary>
        /// 将一根新K线加入序列
        /// </summary>
        /// <param name="openTime">K线开始时间</param>
        /// <param name="price">开盘价</param>
        public void Add(DateTime openTime, double price)
        {
            Bar bar = new Bar(openTime, price);

            this.Add(bar);
        }

        /// <summary>
        /// 价格更新事件处理
        /// </summary>
        /// <param name="price">最新价格</param>
        public void UpdatePrice(QuoteData queueQuoteData)
        {
            if (this[0] == null)
            {
                this.Add(queueQuoteData.UpdateTime, queueQuoteData.Price);
            }
            else
            {
                double span = 0;
                TimeSpan timeSpan = queueQuoteData.UpdateTime - this[0].OpenTime;

                if (this.BarUnit.TimeSpan == BarTimeSpan.Minutes)
                    span = timeSpan.TotalMinutes;
                else
                    span = timeSpan.TotalDays;

                if (span > this.BarUnit.Level)
                {
                    //引发K线完成事件
                    if (BarClose != null) BarClose(this);

                    //加入新的K线
                    this.Add(queueQuoteData.UpdateTime, queueQuoteData.Price);

                    //引发K线新开事件
                    if (BarOpen != null) BarOpen(this);
                }
            }

            //更新K线收盘价
            this[0].UpdatePrice(queueQuoteData.Price);

            //引发价格更新事件
            if (PriceUpdate != null) PriceUpdate(this);
        }

    }
}
